#include "stdafx.h"
#include "jc.h"

class JStringPool
{
	typedef struct RawString
	{
		wchar_t	*text;
		
	}RawString;

	JStringPool(void)
	{
		InitializeCriticalSectionAndSpinCount(&m_cs, 4000);
	}
public:
	~JStringPool(void)
	{
		DeleteCriticalSection(&m_cs);
	}

	JStringPool& getInstance(void)
	{
		static JStringPool pool;
		return pool;
	}

	wchar_t *

	void remove(JString& text)
	{
		unsigned int ref;

		EnterCriticalSection(&m_cs);

		ref = m_stringPool.get(text);
		ref--;
		if(ref == 0)
			m_stringPool.remove(text);
		else
			m_stringPool.set(text, ref);

		LeaveCriticalSection(&m_cs);
	}

private:
	CRITICAL_SECTION m_cs;
	JHashMap<JString, unsigned int> m_stringPool;
};

JString::JString(void)
	:m_data()
{
}

JString::~JString(void)
{
}

JString::operator const wchar_t*(void)
{
	return m_data.getData() ? (const wchar_t *)m_data.getData() : L"";
}

void JString::format(const wchar_t *fmt, ...)
{
	va_list args;
	va_start(args, fmt);
	formatV(fmt, args);
}

void JString::formatV(const wchar_t *fmt, va_list args)
{
	int n;

	m_data.setLength(0);

	if(!fmt || !fmt[0])
		return;

	n = _vscwprintf(fmt, args);

	m_data.ensure((n + 1) * sizeof(wchar_t));
	vswprintf((wchar_t *)m_data.getData(), fmt, args);
	m_data.setLength(n * sizeof(wchar_t));
}

BOOL JString::getEnvironmentVariable(const wchar_t *varname)
{
	DWORD r, c;

	if(!varname || !varname[0])
		THROW_JEXCEPTION(L"Except variable name.");

	m_data.ensure(256);

	while(1)
	{
		c = m_data.getCapacity() / sizeof(wchar_t);
		r = GetEnvironmentVariable(varname, (wchar_t *)m_data.getData(), c);
		if(r == 0)
		{
			r = GetLastError();
			if(r == ERROR_ENVVAR_NOT_FOUND)
			{
				m_data.setLength(0);
				return FALSE;
			}
			else
				THROW_JEXCEPTION_WIN(r, L"Get variable name '%s' failed.", varname);
		}
		else if(r < c)
		{
			m_data.setLength(r * sizeof(wchar_t));
			return TRUE;
		}
		else if(r >= c)
			m_data.ensure(r * sizeof(wchar_t));
	}
}

#if _DEBUG
void JString::Test(void)
{
	JString js;
	js.getEnvironmentVariable(L"NUMBER_OF_PROCESSORS");
	const wchar_t *p = js;

}
#endif
